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

#include <linux/types.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/net.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

#define ROUND_UP(x) (((x)+3) & ~3)

/* 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, 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_alloc(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;
		}
	}

	memset(req, 0, sizeof(struct smb_request));
	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 (signalled() && (server->flags & NFS_MOUNT_INTR))
			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);

	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 = ROUND_UP(header + 3);
	const int odata  = ROUND_UP(oparam + req->rq_lparm);
	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;
}
