/*
 *  request.c
 *
 *  Copyright (C) 2001 by Urban Widmark
 *
 *  Please add a note about your changes to smbfs in the ChangeLog file.
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/net.h>
#include <linux/sched.h>

#include <linux/smb_fs.h>
#include <linux/smbno.h>
#include <linux/smb_mount.h>

#include "smb_debug.h"
#include "request.h"
#include "proto.h"

/* #define SMB_SLAB_DEBUG	(SLAB_RED_ZONE | SLAB_POISON) */
#define SMB_SLAB_DEBUG	0

/* cache for request structures */
static struct kmem_cache *req_cachep;

static int smb_request_send_req(struct smb_request *req);

/*
  /proc/slabinfo:
  name, active, num, objsize, active_slabs, num_slaps, #pages
*/


int smb_init_request_cache(void)
{
	req_cachep = kmem_cache_create("smb_request",
				       sizeof(struct smb_request), 0,
				       SMB_SLAB_DEBUG | SLAB_HWCACHE_ALIGN,
				       NULL);
	if (req_cachep == NULL)
		return -ENOMEM;

	return 0;
}

void smb_destroy_request_cache(void)
{
	kmem_cache_destroy(req_cachep);
}

/*
 * Allocate and initialise a request structure
 */
static struct smb_request *smb_do_alloc_request(struct smb_sb_info *server,
						int bufsize)
{
	struct smb_request *req;
	unsigned char *buf = NULL;

	req = kmem_cache_zalloc(req_cachep, GFP_KERNEL);
	VERBOSE("allocating request: %p\n", req);
	if (!req)
		goto out;

	if (bufsize > 0) {
		buf = kmalloc(bufsize, GFP_NOFS);
		if (!buf) {
			kmem_cache_free(req_cachep, req);
			return NULL;
		}
	}

	req->rq_buffer = buf;
	req->rq_bufsize = bufsize;
	req->rq_server = server;
	init_waitqueue_head(&req->rq_wait);
	INIT_LIST_HEAD(&req->rq_queue);
	atomic_set(&req->rq_count, 1);

out:
	return req;
}

struct smb_request *smb_alloc_request(struct smb_sb_info *server, int bufsize)
{
	struct smb_request *req = NULL;

	for (;;) {
		atomic_inc(&server->nr_requests);
		if (atomic_read(&server->nr_requests) <= MAX_REQUEST_HARD) {
			req = smb_do_alloc_request(server, bufsize);
			if (req != NULL)
				break;
		}

#if 0
		/*
		 * Try to free up at least one request in order to stay
		 * below the hard limit
		 */
                if (nfs_try_to_free_pages(server))
			continue;

		if (fatal_signal_pending(current))
			return ERR_PTR(-ERESTARTSYS);
		current->policy = SCHED_YIELD;
		schedule();
#else
		/* FIXME: we want something like nfs does above, but that
		   requires changes to all callers and can wait. */
		break;
#endif
	}
	return req;
}

static void smb_free_request(struct smb_request *req)
{
	atomic_dec(&req->rq_server->nr_requests);
	if (req->rq_buffer && !(req->rq_flags & SMB_REQ_STATIC))
		kfree(req->rq_buffer);
	kfree(req->rq_trans2buffer);
	kmem_cache_free(req_cachep, req);
}

/*
 * What prevents a rget to race with a rput? The count must never drop to zero
 * while it is in use. Only rput if it is ok that it is free'd.
 */
static void smb_rget(struct smb_request *req)
{
	atomic_inc(&req->rq_count);
}
void smb_rput(struct smb_request *req)
{
	if (atomic_dec_and_test(&req->rq_count)) {
		list_del_init(&req->rq_queue);
		smb_free_request(req);
	}
}

/* setup to receive the data part of the SMB */
static int smb_setup_bcc(struct smb_request *req)
{
	int result = 0;
	req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd;

	if (req->rq_rlen > req->rq_bufsize) {
		PARANOIA("Packet too large %d > %d\n",
			 req->rq_rlen, req->rq_bufsize);
		return -ENOBUFS;
	}

	req->rq_iov[0].iov_base = req->rq_buffer;
	req->rq_iov[0].iov_len  = req->rq_rlen;
	req->rq_iovlen = 1;

	return result;
}

/*
 * Prepare a "normal" request structure.
 */
static int smb_setup_request(struct smb_request *req)
{
	int len = smb_len(req->rq_header) + 4;
	req->rq_slen = len;

	/* if we expect a data part in the reply we set the iov's to read it */
	if (req->rq_resp_bcc)
		req->rq_setup_read = smb_setup_bcc;

	/* This tries to support re-using the same request */
	req->rq_bytes_sent = 0;
	req->rq_rcls = 0;
	req->rq_err = 0;
	req->rq_errno = 0;
	req->rq_fragment = 0;
	kfree(req->rq_trans2buffer);
	req->rq_trans2buffer = NULL;

	return 0;
}

/*
 * Prepare a transaction2 request structure
 */
static int smb_setup_trans2request(struct smb_request *req)
{
	struct smb_sb_info *server = req->rq_server;
	int mparam, mdata;
	static unsigned char padding[4];

	/* I know the following is very ugly, but I want to build the
	   smb packet as efficiently as possible. */

	const int smb_parameters = 15;
	const int header = SMB_HEADER_LEN + 2 * smb_parameters + 2;
	const int oparam = ALIGN(header + 3, sizeof(u32));
	const int odata  = ALIGN(oparam + req->rq_lparm, sizeof(u32));
	const int bcc = (req->rq_data ? odata + req->rq_ldata :
					oparam + req->rq_lparm) - header;

	if ((bcc + oparam) > server->opt.max_xmit)
		return -ENOMEM;
	smb_setup_header(req, SMBtrans2, smb_parameters, bcc);

	/*
	 * max parameters + max data + max setup == bufsize to make NT4 happy
	 * and not abort the transfer or split into multiple responses. It also
	 * makes smbfs happy as handling packets larger than the buffer size
	 * is extra work.
	 *
	 * OS/2 is probably going to hate me for this ...
	 */
	mparam = SMB_TRANS2_MAX_PARAM;
	mdata = req->rq_bufsize - mparam;

	mdata = server->opt.max_xmit - mparam - 100;
	if (mdata < 1024) {
		mdata = 1024;
		mparam = 20;
	}

#if 0
	/* NT/win2k has ~4k max_xmit, so with this we request more than it wants
	   to return as one SMB. Useful for testing the fragmented trans2
	   handling. */
	mdata = 8192;
#endif

	WSET(req->rq_header, smb_tpscnt, req->rq_lparm);
	WSET(req->rq_header, smb_tdscnt, req->rq_ldata);
	WSET(req->rq_header, smb_mprcnt, mparam);
	WSET(req->rq_header, smb_mdrcnt, mdata);
	WSET(req->rq_header, smb_msrcnt, 0);    /* max setup always 0 ? */
	WSET(req->rq_header, smb_flags, 0);
	DSET(req->rq_header, smb_timeout, 0);
	WSET(req->rq_header, smb_pscnt, req->rq_lparm);
	WSET(req->rq_header, smb_psoff, oparam - 4);
	WSET(req->rq_header, smb_dscnt, req->rq_ldata);
	WSET(req->rq_header, smb_dsoff, req->rq_data ? odata - 4 : 0);
	*(req->rq_header + smb_suwcnt) = 0x01;          /* setup count */
	*(req->rq_header + smb_suwcnt + 1) = 0x00;      /* reserved */
	WSET(req->rq_header, smb_setup0, req->rq_trans2_command);

	req->rq_iovlen = 2;
	req->rq_iov[0].iov_base = (void *) req->rq_header;
	req->rq_iov[0].iov_len = oparam;
	req->rq_iov[1].iov_base = (req->rq_parm==NULL) ? padding : req->rq_parm;
	req->rq_iov[1].iov_len = req->rq_lparm;
	req->rq_slen = oparam + req->rq_lparm;

	if (req->rq_data) {
		req->rq_iovlen += 2;
		req->rq_iov[2].iov_base = padding;
		req->rq_iov[2].iov_len = odata - oparam - req->rq_lparm;
		req->rq_iov[3].iov_base = req->rq_data;
		req->rq_iov[3].iov_len = req->rq_ldata;
		req->rq_slen = odata + req->rq_ldata;
	}

	/* always a data part for trans2 replies */
	req->rq_setup_read = smb_setup_bcc;

	return 0;
}

/*
 * Add a request and tell smbiod to process it
 */
int smb_add_request(struct smb_request *req)
{
	long timeleft;
	struct smb_sb_info *server = req->rq_server;
	int result = 0;

	smb_setup_request(req);
	if (req->rq_trans2_command) {
		if (req->rq_buffer == NULL) {
			PARANOIA("trans2 attempted without response buffer!\n");
			return -EIO;
		}
		result = smb_setup_trans2request(req);
	}
	if (result < 0)
		return result;

#ifdef SMB_DEBUG_PACKET_SIZE
	add_xmit_stats(req);
#endif

	/* add 'req' to the queue of requests */
	if (smb_lock_server_interruptible(server))
		return -EINTR;

	/*
	 * Try to send the request as the process. If that fails we queue the
	 * request and let smbiod send it later.
	 */

	/* FIXME: each server has a number on the maximum number of parallel
	   requests. 10, 50 or so. We should not allow more requests to be
	   active. */
	if (server->mid > 0xf000)
		server->mid = 0;
	req->rq_mid = server->mid++;
	WSET(req->rq_header, smb_mid, req->rq_mid);

	result = 0;
	if (server->state == CONN_VALID) {
		if (list_empty(&server->xmitq))
			result = smb_request_send_req(req);
		if (result < 0) {
			/* Connection lost? */
			server->conn_error = result;
			server->state = CONN_INVALID;
		}
	}
	if (result != 1)
		list_add_tail(&req->rq_queue, &server->xmitq);
	smb_rget(req);

	if (server->state != CONN_VALID)
		smbiod_retry(server);

	smb_unlock_server(server);

	smbiod_wake_up();

	timeleft = wait_event_interruptible_timeout(req->rq_wait,
				    req->rq_flags & SMB_REQ_RECEIVED, 30*HZ);
	if (!timeleft || signal_pending(current)) {
		/*
		 * On timeout or on interrupt we want to try and remove the
		 * request from the recvq/xmitq.
		 * First check if the request is still part of a queue. (May
		 * have been removed by some error condition)
		 */
		smb_lock_server(server);
		if (!list_empty(&req->rq_queue)) {
			list_del_init(&req->rq_queue);
			smb_rput(req);
		}
		smb_unlock_server(server);
	}

	if (!timeleft) {
		PARANOIA("request [%p, mid=%d] timed out!\n",
			 req, req->rq_mid);
		VERBOSE("smb_com:  %02x\n", *(req->rq_header + smb_com));
		VERBOSE("smb_rcls: %02x\n", *(req->rq_header + smb_rcls));
		VERBOSE("smb_flg:  %02x\n", *(req->rq_header + smb_flg));
		VERBOSE("smb_tid:  %04x\n", WVAL(req->rq_header, smb_tid));
		VERBOSE("smb_pid:  %04x\n", WVAL(req->rq_header, smb_pid));
		VERBOSE("smb_uid:  %04x\n", WVAL(req->rq_header, smb_uid));
		VERBOSE("smb_mid:  %04x\n", WVAL(req->rq_header, smb_mid));
		VERBOSE("smb_wct:  %02x\n", *(req->rq_header + smb_wct));

		req->rq_rcls = ERRSRV;
		req->rq_err  = ERRtimeout;

		/* Just in case it was "stuck" */
		smbiod_wake_up();
	}
	VERBOSE("woke up, rcls=%d\n", req->rq_rcls);

	if (req->rq_rcls != 0)
		req->rq_errno = smb_errno(req);
	if (signal_pending(current))
		req->rq_errno = -ERESTARTSYS;
	return req->rq_errno;
}

/*
 * Send a request and place it on the recvq if successfully sent.
 * Must be called with the server lock held.
 */
static int smb_request_send_req(struct smb_request *req)
{
	struct smb_sb_info *server = req->rq_server;
	int result;

	if (req->rq_bytes_sent == 0) {
		WSET(req->rq_header, smb_tid, server->opt.tid);
		WSET(req->rq_header, smb_pid, 1);
		WSET(req->rq_header, smb_uid, server->opt.server_uid);
	}

	result = smb_send_request(req);
	if (result < 0 && result != -EAGAIN)
		goto out;

	result = 0;
	if (!(req->rq_flags & SMB_REQ_TRANSMITTED))
		goto out;

	list_move_tail(&req->rq_queue, &server->recvq);
	result = 1;
out:
	return result;
}

/*
 * Sends one request for this server. (smbiod)
 * Must be called with the server lock held.
 * Returns: <0 on error
 *           0 if no request could be completely sent
 *           1 if all data for one request was sent
 */
int smb_request_send_server(struct smb_sb_info *server)
{
	struct list_head *head;
	struct smb_request *req;
	int result;

	if (server->state != CONN_VALID)
		return 0;

	/* dequeue first request, if any */
	req = NULL;
	head = server->xmitq.next;
	if (head != &server->xmitq) {
		req = list_entry(head, struct smb_request, rq_queue);
	}
	if (!req)
		return 0;

	result = smb_request_send_req(req);
	if (result < 0) {
		server->conn_error = result;
		list_move(&req->rq_queue, &server->xmitq);
		result = -EIO;
		goto out;
	}

out:
	return result;
}

/*
 * Try to find a request matching this "mid". Typically the first entry will
 * be the matching one.
 */
static struct smb_request *find_request(struct smb_sb_info *server, int mid)
{
	struct list_head *tmp;
	struct smb_request *req = NULL;

	list_for_each(tmp, &server->recvq) {
		req = list_entry(tmp, struct smb_request, rq_queue);
		if (req->rq_mid == mid) {
			break;
		}
		req = NULL;
	}

	if (!req) {
		VERBOSE("received reply with mid %d but no request!\n",
			WVAL(server->header, smb_mid));
		server->rstate = SMB_RECV_DROP;
	}

	return req;
}

/*
 * Called when we have read the smb header and believe this is a response.
 */
static int smb_init_request(struct smb_sb_info *server, struct smb_request *req)
{
	int hdrlen, wct;

	memcpy(req->rq_header, server->header, SMB_HEADER_LEN);

	wct = *(req->rq_header + smb_wct);
	if (wct > 20) {	
		PARANOIA("wct too large, %d > 20\n", wct);
		server->rstate = SMB_RECV_DROP;
		return 0;
	}

	req->rq_resp_wct = wct;
	hdrlen = SMB_HEADER_LEN + wct*2 + 2;
	VERBOSE("header length: %d   smb_wct: %2d\n", hdrlen, wct);

	req->rq_bytes_recvd = SMB_HEADER_LEN;
	req->rq_rlen = hdrlen;
	req->rq_iov[0].iov_base = req->rq_header;
	req->rq_iov[0].iov_len  = hdrlen;
	req->rq_iovlen = 1;
	server->rstate = SMB_RECV_PARAM;

#ifdef SMB_DEBUG_PACKET_SIZE
	add_recv_stats(smb_len(server->header));
#endif
	return 0;
}

/*
 * Reads the SMB parameters
 */
static int smb_recv_param(struct smb_sb_info *server, struct smb_request *req)
{
	int result;

	result = smb_receive(server, req);
	if (result < 0)
		return result;
	if (req->rq_bytes_recvd < req->rq_rlen)
		return 0;

	VERBOSE("result: %d   smb_bcc:  %04x\n", result,
		WVAL(req->rq_header, SMB_HEADER_LEN +
		     (*(req->rq_header + smb_wct) * 2)));

	result = 0;
	req->rq_iov[0].iov_base = NULL;
	req->rq_rlen = 0;
	if (req->rq_callback)
		req->rq_callback(req);
	else if (req->rq_setup_read)
		result = req->rq_setup_read(req);
	if (result < 0) {
		server->rstate = SMB_RECV_DROP;
		return result;
	}

	server->rstate = req->rq_rlen > 0 ? SMB_RECV_DATA : SMB_RECV_END;

	req->rq_bytes_recvd = 0;	// recvd out of the iov

	VERBOSE("rlen: %d\n", req->rq_rlen);
	if (req->rq_rlen < 0) {
		PARANOIA("Parameters read beyond end of packet!\n");
		server->rstate = SMB_RECV_END;
		return -EIO;
	}
	return 0;
}

/*
 * Reads the SMB data
 */
static int smb_recv_data(struct smb_sb_info *server, struct smb_request *req)
{
	int result;

	result = smb_receive(server, req);
	if (result < 0)
		goto out;
	if (req->rq_bytes_recvd < req->rq_rlen)
		goto out;
	server->rstate = SMB_RECV_END;
out:
	VERBOSE("result: %d\n", result);
	return result;
}

/*
 * Receive a transaction2 response
 * Return: 0 if the response has been fully read
 *         1 if there are further "fragments" to read
 *        <0 if there is an error
 */
static int smb_recv_trans2(struct smb_sb_info *server, struct smb_request *req)
{
	unsigned char *inbuf;
	unsigned int parm_disp, parm_offset, parm_count, parm_tot;
	unsigned int data_disp, data_offset, data_count, data_tot;
	int hdrlen = SMB_HEADER_LEN + req->rq_resp_wct*2 - 2;

	VERBOSE("handling trans2\n");

	inbuf = req->rq_header;
	data_tot    = WVAL(inbuf, smb_tdrcnt);
	parm_tot    = WVAL(inbuf, smb_tprcnt);
	parm_disp   = WVAL(inbuf, smb_prdisp);
	parm_offset = WVAL(inbuf, smb_proff);
	parm_count  = WVAL(inbuf, smb_prcnt);
	data_disp   = WVAL(inbuf, smb_drdisp);
	data_offset = WVAL(inbuf, smb_droff);
	data_count  = WVAL(inbuf, smb_drcnt);

	/* Modify offset for the split header/buffer we use */
	if (data_count || data_offset) {
		if (unlikely(data_offset < hdrlen))
			goto out_bad_data;
		else
			data_offset -= hdrlen;
	}
	if (parm_count || parm_offset) {
		if (unlikely(parm_offset < hdrlen))
			goto out_bad_parm;
		else
			parm_offset -= hdrlen;
	}

	if (parm_count == parm_tot && data_count == data_tot) {
		/*
		 * This packet has all the trans2 data.
		 *
		 * We setup the request so that this will be the common
		 * case. It may be a server error to not return a
		 * response that fits.
		 */
		VERBOSE("single trans2 response  "
			"dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
			data_count, parm_count,
			data_offset, parm_offset);
		req->rq_ldata = data_count;
		req->rq_lparm = parm_count;
		req->rq_data = req->rq_buffer + data_offset;
		req->rq_parm = req->rq_buffer + parm_offset;
		if (unlikely(parm_offset + parm_count > req->rq_rlen))
			goto out_bad_parm;
		if (unlikely(data_offset + data_count > req->rq_rlen))
			goto out_bad_data;
		return 0;
	}

	VERBOSE("multi trans2 response  "
		"frag=%d, dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
		req->rq_fragment,
		data_count, parm_count,
		data_offset, parm_offset);

	if (!req->rq_fragment) {
		int buf_len;

		/* We got the first trans2 fragment */
		req->rq_fragment = 1;
		req->rq_total_data = data_tot;
		req->rq_total_parm = parm_tot;
		req->rq_ldata = 0;
		req->rq_lparm = 0;

		buf_len = data_tot + parm_tot;
		if (buf_len > SMB_MAX_PACKET_SIZE)
			goto out_too_long;

		req->rq_trans2bufsize = buf_len;
		req->rq_trans2buffer = kzalloc(buf_len, GFP_NOFS);
		if (!req->rq_trans2buffer)
			goto out_no_mem;

		req->rq_parm = req->rq_trans2buffer;
		req->rq_data = req->rq_trans2buffer + parm_tot;
	} else if (unlikely(req->rq_total_data < data_tot ||
			    req->rq_total_parm < parm_tot))
		goto out_data_grew;

	if (unlikely(parm_disp + parm_count > req->rq_total_parm ||
		     parm_offset + parm_count > req->rq_rlen))
		goto out_bad_parm;
	if (unlikely(data_disp + data_count > req->rq_total_data ||
		     data_offset + data_count > req->rq_rlen))
		goto out_bad_data;

	inbuf = req->rq_buffer;
	memcpy(req->rq_parm + parm_disp, inbuf + parm_offset, parm_count);
	memcpy(req->rq_data + data_disp, inbuf + data_offset, data_count);

	req->rq_ldata += data_count;
	req->rq_lparm += parm_count;

	/*
	 * Check whether we've received all of the data. Note that
	 * we use the packet totals -- total lengths might shrink!
	 */
	if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) {
		req->rq_ldata = data_tot;
		req->rq_lparm = parm_tot;
		return 0;
	}
	return 1;

out_too_long:
	printk(KERN_ERR "smb_trans2: data/param too long, data=%u, parm=%u\n",
		data_tot, parm_tot);
	goto out_EIO;
out_no_mem:
	printk(KERN_ERR "smb_trans2: couldn't allocate data area of %d bytes\n",
	       req->rq_trans2bufsize);
	req->rq_errno = -ENOMEM;
	goto out;
out_data_grew:
	printk(KERN_ERR "smb_trans2: data/params grew!\n");
	goto out_EIO;
out_bad_parm:
	printk(KERN_ERR "smb_trans2: invalid parms, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
	       parm_disp, parm_count, parm_tot, parm_offset);
	goto out_EIO;
out_bad_data:
	printk(KERN_ERR "smb_trans2: invalid data, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
	       data_disp, data_count, data_tot, data_offset);
out_EIO:
	req->rq_errno = -EIO;
out:
	return req->rq_errno;
}

/*
 * State machine for receiving responses. We handle the fact that we can't
 * read the full response in one try by having states telling us how much we
 * have read.
 *
 * Must be called with the server lock held (only called from smbiod).
 *
 * Return: <0 on error
 */
int smb_request_recv(struct smb_sb_info *server)
{
	struct smb_request *req = NULL;
	int result = 0;

	if (smb_recv_available(server) <= 0)
		return 0;

	VERBOSE("state: %d\n", server->rstate);
	switch (server->rstate) {
	case SMB_RECV_DROP:
		result = smb_receive_drop(server);
		if (result < 0)
			break;
		if (server->rstate == SMB_RECV_DROP)
			break;
		server->rstate = SMB_RECV_START;
		/* fallthrough */
	case SMB_RECV_START:
		server->smb_read = 0;
		server->rstate = SMB_RECV_HEADER;
		/* fallthrough */
	case SMB_RECV_HEADER:
		result = smb_receive_header(server);
		if (result < 0)
			break;
		if (server->rstate == SMB_RECV_HEADER)
			break;
		if (! (*(server->header + smb_flg) & SMB_FLAGS_REPLY) ) {
			server->rstate = SMB_RECV_REQUEST;
			break;
		}
		if (server->rstate != SMB_RECV_HCOMPLETE)
			break;
		/* fallthrough */
	case SMB_RECV_HCOMPLETE:
		req = find_request(server, WVAL(server->header, smb_mid));
		if (!req)
			break;
		smb_init_request(server, req);
		req->rq_rcls = *(req->rq_header + smb_rcls);
		req->rq_err  = WVAL(req->rq_header, smb_err);
		if (server->rstate != SMB_RECV_PARAM)
			break;
		/* fallthrough */
	case SMB_RECV_PARAM:
		if (!req)
			req = find_request(server,WVAL(server->header,smb_mid));
		if (!req)
			break;
		result = smb_recv_param(server, req);
		if (result < 0)
			break;
		if (server->rstate != SMB_RECV_DATA)
			break;
		/* fallthrough */
	case SMB_RECV_DATA:
		if (!req)
			req = find_request(server,WVAL(server->header,smb_mid));
		if (!req)
			break;
		result = smb_recv_data(server, req);
		if (result < 0)
			break;
		break;

		/* We should never be called with any of these states */
	case SMB_RECV_END:
	case SMB_RECV_REQUEST:
		BUG();
	}

	if (result < 0) {
		/* We saw an error */
		return result;
	}

	if (server->rstate != SMB_RECV_END)
		return 0;

	result = 0;
	if (req->rq_trans2_command && req->rq_rcls == SUCCESS)
		result = smb_recv_trans2(server, req);

	/*
	 * Response completely read. Drop any extra bytes sent by the server.
	 * (Yes, servers sometimes add extra bytes to responses)
	 */
	VERBOSE("smb_len: %d   smb_read: %d\n",
		server->smb_len, server->smb_read);
	if (server->smb_read < server->smb_len)
		smb_receive_drop(server);

	server->rstate = SMB_RECV_START;

	if (!result) {
		list_del_init(&req->rq_queue);
		req->rq_flags |= SMB_REQ_RECEIVED;
		smb_rput(req);
		wake_up_interruptible(&req->rq_wait);
	}
	return 0;
}
