/*
 *  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 kmem_cache_t *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, SLAB_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;
}
